package com.ttx.algorithm.leetcode.usual;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;

import java.util.*;

/**
 * https://leetcode-cn.com/problems/my-calendar-i/
 *
 * 实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内没有其他安排，则可以存储这个新的日程安排。
 *
 * MyCalendar 有一个 book(int start, int end)方法。它意味着在 start 到 end 时间内增加一个日程安排，注意，这里的时间是半开区间，即 [start, end), 实数 x 的范围为，  start <= x < end。
 *
 * 当两个日程安排有一些时间上的交叉时（例如两个日程安排都在同一时间内），就会产生重复预订。
 *
 * 每次调用 MyCalendar.book方法时，如果可以将日程安排成功添加到日历中而不会导致重复预订，返回 true。否则，返回 false 并且不要将该日程安排添加到日历中。
 *
 * 请按照以下步骤调用 MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)
 *
 * 示例 1:
 *
 * MyCalendar();
 * MyCalendar.book(10, 20); // returns true
 * MyCalendar.book(15, 25); // returns false
 * MyCalendar.book(20, 30); // returns true
 * 解释:
 * 第一个日程安排可以添加到日历中.  第二个日程安排不能添加到日历中，因为时间 15 已经被第一个日程安排预定了。
 * 第三个日程安排可以添加到日历中，因为第一个日程安排并不包含时间 20 。
 *
 * 说明:
 *
 *     每个测试用例，调用 MyCalendar.book 函数最多不超过 100次。
 *     调用函数 MyCalendar.book(start, end)时， start 和 end 的取值范围为 [0, 10^9]。
 *
 * @author TimFruit
 * @date 20-5-2 下午3:58
 */
public class P729MyCalendar1 {
    public static void main(String[] args) {

        MyCalendar myCalendar=new MyCalendar();

        String paramString="[[47,50],[33,41],[39,45],[33,42],[25,32],[26,35],[19,25],[3,8],[8,13],[18,27]]";

        String expectedResult="[true,true,false,false,true,false,true,true,true,false]";


        List<Boolean> resultList=new ArrayList<>();

        List<Integer> params=param(paramString);

        System.out.println(params);


        for(int i=0;i<params.size();i+=2){
            boolean re=myCalendar.book(params.get(i), params.get(i+1));
            resultList.add(re);
        }



        String resultString=resultList.toString().replace(" ","");
        System.out.println(resultString);
        Assert.state(expectedResult.equals(resultString));


    }

    private static List<Integer> param(String paramString){
        // [[],[47,50],[33,41],[39,45],[33,42],[25,32],[26,35],[19,25],[3,8],[8,13],[18,27]]
        paramString=paramString.replace("[","").replace("]","");
        String[] strs=paramString.split(",");

        List<Integer> list=new ArrayList<>();
        String key=null;
        String value=null;
        int i=0;
        for(;i<strs.length;i++){


            list.add(Integer.valueOf(strs[i]));

        }

        return list;
    }








static     class MyCalendar {

        // [start, end)
        TreeMap<Integer,Integer> planTree=new TreeMap<>();

        Map.Entry<Integer, Integer> firstEntry =null;
        Map.Entry<Integer, Integer> secondEntry =null;

        boolean couldBook=false;


        public MyCalendar() {

        }

        public boolean book(int start, int end) {



            firstEntry =null;
            secondEntry =null;
            couldBook=false;



            //<=
            firstEntry=planTree.floorEntry(start);

            //>=
            secondEntry=planTree.ceilingEntry(start);



            if(firstEntry==null){
                if(secondEntry==null){//两个都不存在，数据为空
                    couldBook=true;
                    planTree.put(start,end);
                }else {
                    //firstEntry==null &&  sceondEntry.key>= start
                    if(end<=secondEntry.getKey()){
                        couldBook=true;
                        planTree.put(start,end);
                    }
                }
            }else {
                if(secondEntry==null){
                    // firstEntry.key<= start && secondEntry=null

                    if(firstEntry.getValue()<=start){
                        couldBook=true;
                        planTree.put(start,end);
                    }


                }else {
                    //firstEntry.key<=start && start <= secondEntry.key


                    if(firstEntry.getValue()<=start && end <= secondEntry.getKey()
                            && firstEntry.getKey().intValue()!=secondEntry.getKey()){
                        couldBook=true;
                        planTree.put(start,end);
                    }
                }

            }



            return couldBook;
        }
    }
}
